[XEN] Scheduling hypercalls defer entry to the scheduler to softirq
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 16 Nov 2006 18:28:05 +0000 (18:28 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 16 Nov 2006 18:28:05 +0000 (18:28 +0000)
context.

This avoids entering the scheduler with outstanding multicall state
and also happens to simplify the x86 entry protocol to the scheduler
hypercall (since we do not need to preset the return code).

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/ia64/vmx/vmx_support.c
xen/arch/x86/x86_32/entry.S
xen/arch/x86/x86_64/entry.S
xen/common/domain.c
xen/common/schedule.c

index cdb4c51be0617823ff6a0a4b7b37a1e401e89075..ea7e24afe88f7c972e8f8f9782f48ac224b89fdb 100644 (file)
@@ -95,8 +95,7 @@ void vmx_send_assist_req(struct vcpu *v)
             break;
         }
 
-        /* I want to call __enter_scheduler() only */
-        do_sched_op_compat(SCHEDOP_yield, 0);
+        raise_softirq(SCHEDULE_SOFTIRQ);
         mb();
     }
 
index 2535858c3ca2117e1b514960289dc44bd2d773b3..0e26f46497a7667ba0ba7b1f4be4aeba454c9a82 100644 (file)
@@ -597,20 +597,6 @@ ENTRY(setup_vm86_frame)
         addl $16,%esp
         ret
 
-do_arch_sched_op_compat:
-        # Ensure we return success even if we return via schedule_tail()
-        xorl %eax,%eax
-        GET_GUEST_REGS(%ecx)
-        movl %eax,UREGS_eax(%ecx)
-        jmp  do_sched_op_compat
-
-do_arch_sched_op:
-        # Ensure we return success even if we return via schedule_tail()
-        xorl %eax,%eax
-        GET_GUEST_REGS(%ecx)
-        movl %eax,UREGS_eax(%ecx)
-        jmp  do_sched_op
-
 .data
 
 ENTRY(exception_table)
@@ -642,7 +628,7 @@ ENTRY(hypercall_table)
         .long do_stack_switch
         .long do_set_callbacks
         .long do_fpu_taskswitch     /*  5 */
-        .long do_arch_sched_op_compat
+        .long do_sched_op_compat
         .long do_platform_op
         .long do_set_debugreg
         .long do_get_debugreg
@@ -665,7 +651,7 @@ ENTRY(hypercall_table)
         .long do_mmuext_op
         .long do_acm_op
         .long do_nmi_op
-        .long do_arch_sched_op
+        .long do_sched_op
         .long do_callback_op        /* 30 */
         .long do_xenoprof_op
         .long do_event_channel_op
@@ -684,7 +670,7 @@ ENTRY(hypercall_args_table)
         .byte 2 /* do_stack_switch      */
         .byte 4 /* do_set_callbacks     */
         .byte 1 /* do_fpu_taskswitch    */  /*  5 */
-        .byte 2 /* do_arch_sched_op_compat */
+        .byte 2 /* do_sched_op_compat   */
         .byte 1 /* do_platform_op       */
         .byte 2 /* do_set_debugreg      */
         .byte 1 /* do_get_debugreg      */
@@ -707,7 +693,7 @@ ENTRY(hypercall_args_table)
         .byte 4 /* do_mmuext_op         */
         .byte 1 /* do_acm_op            */
         .byte 2 /* do_nmi_op            */
-        .byte 2 /* do_arch_sched_op     */
+        .byte 2 /* do_sched_op          */
         .byte 2 /* do_callback_op       */  /* 30 */
         .byte 2 /* do_xenoprof_op       */
         .byte 2 /* do_event_channel_op  */
index 009ff75881fca053579039cc64cde3c4cc9b2419..3f2b8297c7620cedfb589989db5770506a44dbce 100644 (file)
@@ -497,20 +497,6 @@ nmi_in_hypervisor_mode:
         call  do_nmi
         jmp   ret_from_intr
 
-do_arch_sched_op_compat:
-        # Ensure we return success even if we return via schedule_tail()
-        xorl  %eax,%eax
-        GET_GUEST_REGS(%r10)
-        movq  %rax,UREGS_rax(%r10)
-        jmp   do_sched_op_compat
-
-do_arch_sched_op:
-        # Ensure we return success even if we return via schedule_tail()
-        xorl  %eax,%eax
-        GET_GUEST_REGS(%r10)
-        movq  %rax,UREGS_rax(%r10)
-        jmp   do_sched_op
-
 .data
 
 ENTRY(exception_table)
@@ -542,7 +528,7 @@ ENTRY(hypercall_table)
         .quad do_stack_switch
         .quad do_set_callbacks
         .quad do_fpu_taskswitch     /*  5 */
-        .quad do_arch_sched_op_compat
+        .quad do_sched_op_compat
         .quad do_platform_op
         .quad do_set_debugreg
         .quad do_get_debugreg
@@ -565,7 +551,7 @@ ENTRY(hypercall_table)
         .quad do_mmuext_op
         .quad do_acm_op
         .quad do_nmi_op
-        .quad do_arch_sched_op
+        .quad do_sched_op
         .quad do_callback_op        /* 30 */
         .quad do_xenoprof_op
         .quad do_event_channel_op
@@ -584,8 +570,8 @@ ENTRY(hypercall_args_table)
         .byte 2 /* do_stack_switch      */
         .byte 3 /* do_set_callbacks     */
         .byte 1 /* do_fpu_taskswitch    */  /*  5 */
-        .byte 2 /* do_arch_sched_op_compat */
-        .byte 1 /* do_platform_op           */
+        .byte 2 /* do_sched_op_compat   */
+        .byte 1 /* do_platform_op       */
         .byte 2 /* do_set_debugreg      */
         .byte 1 /* do_get_debugreg      */
         .byte 2 /* do_update_descriptor */  /* 10 */
@@ -607,7 +593,7 @@ ENTRY(hypercall_args_table)
         .byte 4 /* do_mmuext_op         */
         .byte 1 /* do_acm_op            */
         .byte 2 /* do_nmi_op            */
-        .byte 2 /* do_arch_sched_op     */
+        .byte 2 /* do_sched_op          */
         .byte 2 /* do_callback_op       */  /* 30 */
         .byte 2 /* do_xenoprof_op       */
         .byte 2 /* do_event_channel_op  */
index 2eac2ed7edff09708c7ead5bfe6d55391a3379a4..238ee037a723dc2df157bf420c7b594b156bd883 100644 (file)
@@ -258,8 +258,18 @@ void __domain_crash_synchronous(void)
 {
     __domain_crash(current->domain);
 
-    /* Flush multicall state before dying. */
-    this_cpu(mc_state).flags = 0;
+    /*
+     * Flush multicall state before dying if a multicall is in progress.
+     * This shouldn't be necessary, but some architectures are calling
+     * domain_crash_synchronous() when they really shouldn't (i.e., from
+     * within hypercall context).
+     */
+    if ( this_cpu(mc_state).flags != 0 )
+    {
+        dprintk(XENLOG_ERR,
+                "FIXME: synchronous domain crash during a multicall!\n");
+        this_cpu(mc_state).flags = 0;
+    }
 
     for ( ; ; )
         do_softirq();
index b333406d8a8bd851cab82729997e2fed7bf880a5..56fcad2232028aaea8d2bdf37ad8ae1eddfa390d 100644 (file)
@@ -60,8 +60,6 @@ static struct scheduler *schedulers[] = {
     NULL
 };
 
-static void __enter_scheduler(void);
-
 static struct scheduler ops;
 
 #define SCHED_OP(fn, ...)                                 \
@@ -270,7 +268,7 @@ static long do_block(void)
     else
     {
         TRACE_2D(TRC_SCHED_BLOCK, v->domain->domain_id, v->vcpu_id);
-        __enter_scheduler();
+        raise_softirq(SCHEDULE_SOFTIRQ);
     }
 
     return 0;
@@ -315,9 +313,9 @@ static long do_poll(struct sched_poll *sched_poll)
         set_timer(&v->poll_timer, sched_poll->timeout);
 
     TRACE_2D(TRC_SCHED_BLOCK, v->domain->domain_id, v->vcpu_id);
-    __enter_scheduler();
+    raise_softirq(SCHEDULE_SOFTIRQ);
 
-    stop_timer(&v->poll_timer);
+    return 0;
 
  out:
     clear_bit(_VCPUF_polling, &v->vcpu_flags);
@@ -329,7 +327,7 @@ static long do_poll(struct sched_poll *sched_poll)
 static long do_yield(void)
 {
     TRACE_2D(TRC_SCHED_YIELD, current->domain->domain_id, current->vcpu_id);
-    __enter_scheduler();
+    raise_softirq(SCHEDULE_SOFTIRQ);
     return 0;
 }
 
@@ -540,7 +538,7 @@ long sched_adjust(struct domain *d, struct xen_domctl_scheduler_op *op)
  * - deschedule the current domain (scheduler independent).
  * - pick a new domain (scheduler dependent).
  */
-static void __enter_scheduler(void)
+static void schedule(void)
 {
     struct vcpu          *prev = current, *next = NULL;
     s_time_t              now = NOW();
@@ -549,6 +547,7 @@ static void __enter_scheduler(void)
     s32                   r_time;     /* time for new dom to run */
 
     ASSERT(!in_irq());
+    ASSERT(this_cpu(mc_state).flags == 0);
 
     perfc_incrc(sched_run);
 
@@ -679,7 +678,7 @@ void __init scheduler_init(void)
 {
     int i;
 
-    open_softirq(SCHEDULE_SOFTIRQ, __enter_scheduler);
+    open_softirq(SCHEDULE_SOFTIRQ, schedule);
 
     for_each_cpu ( i )
     {